package com.david.trade.clear.tcp;

import com.david.trade.common.SimpleArray;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author admin
 */
@Component
@Slf4j
public class ServerInitializer extends ChannelInitializer<SocketChannel>{

    private ServerBootstrap bootstrap;

    private EventLoopGroup boss;

    private EventLoopGroup worker;

    private SimpleArray<TcpHandler> clients;

    public static TcpHandler client;

    private boolean closed;

    AtomicInteger tcpSize = new AtomicInteger(0);

    public boolean start(int port) {
        clients = new SimpleArray(2);
        boss = new NioEventLoopGroup(1);
        worker = new NioEventLoopGroup(4);
        bootstrap = new ServerBootstrap();
        bootstrap.group(boss, worker);
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.option(ChannelOption.SO_BACKLOG, 128);
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.childHandler(this);
        ChannelFuture f = null;
        try {
            f = bootstrap.bind(port).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
            log.error("server start fail---------------", e);
        }
        if (f.isSuccess()) {
            log.info("netty初始化成功");
        } else {
            log.info("netty初始化失败");
        }
        return f.isSuccess();
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        client = new TcpHandler(ch);
        this.add(client);
    }

    public void add(TcpHandler client) {
        if (closed) {
            log.error("closed add fail---------------");
            return;
        }
        clients.add(client);
        int size = this.tcpSize.addAndGet(1);
        log.info("current tcp size={}", size);
    }
}